// CoreEngine.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Utilities/utilities.h" // if you use STL, please include this line AFTER all other include
#include "Globals.h"
#include "Controller/Scene.h"
#include "Controller/Camera.h"

#include "Torus/controller/input_controller.h"
#include "Torus/torus_game.h"

//temp
#include "Object/Object.h"
#include "Object/Model.h"
#include "Object/Vertex.h"
#include "Object/Shader.h"

int Init ( ESContext *esContext )
{
	glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );

	//model
	Model * m = new Model();

	const float r1 = 10.0f;
	const float r2 = 15.0f;
	Vertex data[8];
	data[0].pos.x = 0.0f;					data[0].pos.y = 0.0f;  data[0].pos.z = -r2;
	data[1].pos.x = 0.0f;					data[1].pos.y = 5.0f;  data[1].pos.z = -r2;
	data[2].pos.x = r2 * sin(PI / 4.0f);	data[2].pos.y = 5.0f;  data[2].pos.z = -r2 * cos(PI / 4.0f);
	data[3].pos.x = r2 * sin(PI / 4.0f);	data[3].pos.y = 0.0f;  data[3].pos.z = -r2 * cos(PI / 4.0f);
	data[4].pos.x = 0.0f;					data[4].pos.y = 0.0f;  data[4].pos.z = -r1;
	data[5].pos.x = 0.0f;					data[5].pos.y = 5.0f;  data[5].pos.z = -r1;
	data[6].pos.x = r1 * sin(PI / 4.0f);	data[6].pos.y = 5.0f;  data[6].pos.z = -r1 * cos(PI / 4.0f);
	data[7].pos.x = r1 * sin(PI / 4.0f);	data[7].pos.y = 0.0f;  data[7].pos.z = -r1 * cos(PI / 4.0f);

	GLuint indices[24] = {0,1,2,2,0,3,3,2,6,6,3,7,7,6,5,5,7,4,4,5,1,1,4,0};
	m->InitFromArray(8, 24, data, indices);

	//shader
	Shader * s = new Shader();
	s->SetVSFileName("../Data/simple.vs");
	s->SetFSFileName("../Data/simple.fs");
	s->m_states.push_back(GL_CULL_FACE);
	s->Init();

	//object
	Object * obj = new Object();
	obj->SetModel(m);
	obj->SetShader(s);

	//camera
	Camera * cam = new Camera();
	cam->SetPerspective(0.785f, 1.0f, 1.0f, 1000.0f);
	cam->SetPositionTarget(Vector3(0.0f, 20.0f, -40.0f), Vector3(0.0f, 0.0f, 0.0f));
	cam->UpdateAllParams();

	//add to screen
	SCENE->AddCamera(cam);
	SCENE->AddObject(obj);

	//because when objects in Scene init, they require the resources to be loaded.
	SCENE->Init();

	return 0;
}

void Draw ( ESContext *esContext )
{
	//draw my world
	SCENE->Draw();
	eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );

	//console
	//GAME.render();
}

void Update ( ESContext *esContext, float deltaTime )
{
	SCENE->Update(deltaTime);

	//if (GAME.is_game_end())
	//{
	//	GAME.clean_up();
	//	PostQuitMessage(0);
	//}

	//INPUT.update(deltaTime);
	//GAME.update(deltaTime);
}

void Key ( ESContext *esContext, unsigned char key, bool bIsPressed)
{
	//INPUT.on_key_event(key, bIsPressed);
}

void CleanUp()
{
	//Scene must be destroy after Resource
	//because when objects in Scene destroy, they need the information from resource.
	DESTROY_SCENE
}

int _tmain(int argc, _TCHAR* argv[])
{
	ESContext esContext;

	esInitContext ( &esContext );

	esCreateWindow ( &esContext, "CoreEngine", Globals::screenWidth, Globals::screenHeight, ES_WINDOW_RGB | ES_WINDOW_DEPTH);

	if ( Init ( &esContext ) != 0 )
		return 0;

	esRegisterDrawFunc ( &esContext, Draw );
	esRegisterUpdateFunc ( &esContext, Update );
	esRegisterKeyFunc ( &esContext, Key);

	esMainLoop ( &esContext );

	//releasing OpenGL resources
	CleanUp();

	//identifying memory leaks
	MemoryDump();
	printf("Press any key...\n");
	_getch();

	return 0;
}